using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Collections.Specialized;
using System.Text;
using System.Data.OleDb;
using _18miljard.Config;
using _18miljard.Db;

namespace _18miljard.Mail
{
	public class EMail : XmlDocument
	{
		private string recipients;
		protected string subject;
		private string origBody;
		protected string sendBody;
		private string from;
		private bool bccTo18miljard = false;
		private int dbId;
		private string attachmentPath = null;
		protected bool postScriptumAllowed = true;

		//TODO: set to null on publish
		private const string testHost = null; //"http://localhost:1136/UI/Forms";

		internal EMail(EMail email)
		{
			this.subject = email.subject;
			this.origBody = email.origBody;
			this.sendBody = email.sendBody;
			this.from = email.from;
			this.postScriptumAllowed = email.postScriptumAllowed;
			this.bccTo18miljard = email.bccTo18miljard;

			this.attachmentPath = email.attachmentPath;
		}

		//used by db-retrieval
		internal EMail(int dbId, string recipient, bool bcc, string subject, string body)
		{
			this.dbId = dbId;
			this.recipients = recipient;
			this.bccTo18miljard = bcc;
			this.subject = subject;
			this.sendBody = body;
		}

		internal EMail(string name)
		{
			this.ReadMail(name);
		}

		internal EMail(string name, string body)
		{
			this.ReadMail(name, body);
		}

		public static bool IsEmailAddressValid(string email)
		{
			bool valid = true;

			try
			{
				System.Net.Mail.MailAddress address = new System.Net.Mail.MailAddress(email);

				int dot = address.Host.IndexOf(".");
				if (dot <= 0 || dot >= address.Host.Length - 2)
					throw new Exception("dummy");
			}
			catch
			{
				valid = false;
			}

			return valid;
		}

		protected virtual void ReadMail(string name, string body)
		{
			/* not implemented for EMail, only for AdminMail */
		}

		protected virtual void ReadMail(string name)
		{
			string path = HttpContext.Current.Server.MapPath("/App_Data/Mail.xml");

			this.Load(path);

			XmlNode node = this.SelectSingleNode("/miljard/mail[@name='" + name + "']");

			if (node != null)
			{
				this.subject = node.Attributes["subject"].Value;
				this.from = node.Attributes["from"].Value;
				XmlAttribute attr = node.Attributes["bcc"];
				if (attr != null)
					this.bccTo18miljard = (attr.Value == "true");

					this.origBody = node.InnerText;

				this.ReadPSAllowed(node);
			}

			this.RemoveAll();
		}

		protected void ReadPSAllowed(XmlNode node)
		{
			XmlAttribute attr = node.Attributes["psallowed"];
			if (attr != null)
				this.postScriptumAllowed = XmlConvert.ToBoolean(attr.Value);
		}

		internal void SetSendBody()
		{
			this.SetSendBody(true);
		}

		internal void SetSendBody(bool doSignature)
		{
			StringBuilder str = new StringBuilder(this.origBody, 1024);
			StringBuilder strSubject = new StringBuilder(this.Subject);

			str.Replace("\r\n", "");

			str.Replace("\t", "");

			foreach (string key in MailArguments.MailArgs.Keys)
			{
				string newVal = MailArguments.MailArgs[key];

				if (newVal != null)
				{
					str.Replace(key, newVal);
					strSubject.Replace(key, newVal);
				}
			}
			
			if (doSignature)
				str.Append("<br><br>Met vriendelijke groet,<br><a href=\"http://www.18miljard.nl\">18miljard.nl</a>");

			this.sendBody = str.ToString();
			this.subject = strSubject.ToString();
		}

		internal Query QueueBatch(int mailTextId)
		{
			QueryArguments newMailArgs = new QueryArguments();

			newMailArgs.Add("recipient", this.recipients, OleDbType.Char);
			newMailArgs.Add("textid", mailTextId, OleDbType.Integer);
			newMailArgs.Add("bcc", this.bccTo18miljard, OleDbType.Boolean);
			
			string insertMailQuery = "i_mail";
			if (this.attachmentPath != null)
			{
				newMailArgs.Add("attachment", this.attachmentPath, OleDbType.Char);
				insertMailQuery = "i_mailwithattachment";
			}

			int psId = 0;

			if (this.postScriptumAllowed)
			{
				PostScriptumCollection postScriptums = MailCache.PostScriptums;
				if (postScriptums.CurrentPostScriptum != null)
				{
					PostScriptum ps = postScriptums.CurrentPostScriptum;
					if (postScriptums.RandomValue < ps.Probability)
					{
						psId = ps.Id;
					}
				}
			}

			newMailArgs.Add("psId", psId, OleDbType.Integer);

			Query newMail = new Query(insertMailQuery, newMailArgs);

			return newMail;
		}

		internal QueryCollection QueueBatchSingle(int mailTextId)
		{
			QueryCollection queries = new QueryCollection(WebConfig.MailConnectionParameters);

			QueryArguments newMailTextArgs = new QueryArguments();

			newMailTextArgs.Add("id", mailTextId, OleDbType.Integer);
			newMailTextArgs.Add("subject", this.subject, OleDbType.Char);
			newMailTextArgs.Add("txt", this.sendBody, OleDbType.LongVarWChar);
			Query newMailText = new Query("i_mailtext", newMailTextArgs);

			queries.Add(newMailText);
			queries.Add(this.QueueBatch(mailTextId));

			return queries;
		}

		internal void Queue(int mailTextId)
		{
			//QueryArguments newMailArgs = new QueryArguments();

			//newMailArgs.Add("recipient", this.recipients, OleDbType.Char);
			//newMailArgs.Add("textid", mailTextId, OleDbType.Integer);
			//newMailArgs.Add("bcc", this.bccToLotenDelen, OleDbType.Boolean);
			//Query newMail = new Query("i_mail", newMailArgs);

			Query query = this.QueueBatch(mailTextId);
			query.Execute();
		}

        internal int QueueSingle()
        {
            return this.QueueSingle(true);
        }

		internal int QueueSingle(bool signal)
		{
			QueryArguments newMailTextArgs = new QueryArguments();

			int newId = EMail.GetNextTextId();

			QueryCollection queries = this.QueueBatchSingle(newId);

			queries.Execute();
						
			//newMailTextArgs.Add("id", newId, OleDbType.Integer);
			//newMailTextArgs.Add("subject", this.subject, OleDbType.Char);
			//newMailTextArgs.Add("txt", this.sendBody, OleDbType.LongVarWChar);
			//Query newMailText = new Query("i_mailtext", newMailTextArgs);
			//newMailText.Execute();

			//this.Queue(newId);

			if (signal)
			    Global.MailSignal();

			return newId;
		}

		internal static int GetNextTextId()
		{
			Query query = new Query("s_maxmailtextid");
			object oMaxId = query.Execute();
			int maxId;
			if (oMaxId == null || oMaxId.GetType() == typeof(System.DBNull))
				maxId = 0;
			else
				maxId = (int)oMaxId;

			return maxId + 1;
		}

		internal string Recipients
		{
			get { return this.recipients; }
			set { this.recipients = value; }
		}

		internal bool Bcc
		{
			get { return this.bccTo18miljard; }
			set { this.bccTo18miljard = value; }
		}

		internal string AttachmentPath
		{
			get { return this.attachmentPath; }
			set { this.attachmentPath = value; }
		}

		internal string Subject
		{
			get { return this.subject; }
		}

		internal string OrigBody
		{
			get { return this.origBody; }
		}

		internal string SendBody
		{
			get { return this.sendBody; }
		}

		internal string From
		{
			get { return this.from; }
		}

        internal int DBId
        {
            get { return this.dbId; }
        }
	}
}
